home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / src / WBBump_src.lha / WBBump_src / threads.e < prev    next >
Encoding:
Text File  |  1999-06-30  |  4.7 KB  |  262 lines

  1. /* ********* */
  2. /* threads.e */
  3. /* ********* */
  4.  
  5.  
  6.  
  7. /*
  8.     WBBump - Bumpmapping on the Workbench!
  9.  
  10.     Copyright (C) 1999  Thomas Jensen - dm98411@edb.tietgen.dk
  11.  
  12.     This program is free software; you can redistribute it and/or modify
  13.     it under the terms of the GNU General Public License as published by
  14.     the Free Software Foundation; either version 2 of the License, or
  15.     (at your option) any later version.
  16.  
  17.     This program is distributed in the hope that it will be useful,
  18.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.     GNU General Public License for more details.
  21.  
  22.     You should have received a copy of the GNU General Public License
  23.     along with this program; if not, write to the Free Software Foundation,
  24.     Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  25. */
  26.  
  27.  
  28. /*
  29.     Needs utility.library to be opened
  30. */
  31.  
  32.  
  33. OPT MODULE
  34.  
  35.  
  36. MODULE    'dos/dos',
  37.         'dos/dostags',
  38.         'dos/dosextens',
  39.  
  40.         'exec/ports',
  41.         'exec/nodes',
  42.         'exec/memory',
  43.         'exec/tasks',
  44.  
  45.         'amigalib/ports',
  46.  
  47.         'utility',
  48.         'utility/tagitem',
  49.  
  50.         'other/a4',
  51.  
  52.         '*errors'
  53.  
  54.  
  55. EXPORT ENUM    TSTAT_RUNNING,
  56.             TSTAT_DEAD
  57.  
  58. EXPORT OBJECT thread
  59.     process        :    PTR TO process
  60.     status        :    LONG
  61.     myport        :    PTR TO mp
  62.     threadport    :    PTR TO mp
  63.     startjob    :    PTR TO job
  64. ENDOBJECT
  65.  
  66.  
  67. EXPORT ENUM    TCMD_STARTUPMSG
  68.  
  69. EXPORT CONST    TCMD_USER=$80000000
  70.  
  71. ENUM    JSTAT_SEND,
  72.         JSTAT_WORKING,
  73.         JSTAT_ABORTED,
  74.         JSTAT_DONE
  75.  
  76.  
  77. EXPORT ENUM    TTAG_CREATE_APENDNAME = TAG_USER,
  78.             TTAG_CREATE_PRIORITY,
  79.             TTAG_CREATE_RELATIVEPRI
  80.  
  81. EXPORT OBJECT job OF mn
  82.     command    :    LONG        -> TCMD_xxx
  83.     input    :    PTR TO LONG
  84.     result    :    LONG
  85.     status    :    LONG
  86. ENDOBJECT
  87.  
  88.  
  89.  
  90.  
  91. PROC create(codeptr, name, tags=NIL:PTR TO tagitem) OF thread HANDLE
  92.     DEF    me=NIL:PTR TO process,
  93.         apendname=FALSE,
  94.         priority,
  95.         threadname=NIL
  96.  
  97.     seta4()
  98.  
  99.     self.status := TSTAT_DEAD
  100.  
  101.     me := FindTask(NIL)
  102.  
  103.     self.myport := createPort(NIL, 0)
  104.     IF self.myport = NIL THEN Raise(ERR_CREATEPORT)
  105.  
  106.  
  107.     IF tags
  108.         apendname := GetTagData(TTAG_CREATE_APENDNAME, FALSE, tags)
  109.         priority := GetTagData(TTAG_CREATE_PRIORITY, me.task.ln.pri, tags)
  110.         priority := priority + GetTagData(TTAG_CREATE_RELATIVEPRI, 0, tags)
  111.     ENDIF
  112.  
  113.  
  114.     IF apendname
  115.         threadname := String(StrLen(me.task.ln.name) + StrLen(name) + 10)
  116.         StringF(threadname, '\s - \s', me.task.ln.name, name)
  117.     ELSE
  118.         threadname := name
  119.     ENDIF
  120.  
  121.     self.process := CreateNewProc([
  122.         NP_ENTRY,        {thread_main},
  123.         NP_NAME,        threadname,
  124.         NP_PRIORITY,    priority,
  125.         NIL])
  126.     IF self.process = NIL THEN eThrow(ERR_THREAD, 'Unable to create thread: "%s"', [threadname])
  127.  
  128.     self.status := TSTAT_RUNNING
  129.  
  130.     self.threadport := self.process.msgport
  131.  
  132.     self.startjob := self.sendjob(TCMD_STARTUPMSG, [self.myport, codeptr, self])
  133.  
  134.     self.threadport := self.waitjob(self.startjob)
  135.  
  136. EXCEPT DO
  137.     IF exception THEN self.end()
  138.     ReThrow()
  139. ENDPROC
  140.  
  141.  
  142.  
  143. PROC end() OF thread
  144.     self.break()
  145.     WHILE self.status = TSTAT_RUNNING
  146.         self.break()
  147.         Delay(10)
  148.     ENDWHILE
  149. ENDPROC
  150.  
  151.  
  152.  
  153. PROC sendjob(cmd, input) OF thread HANDLE
  154.     DEF    job=NIL:PTR TO job
  155.  
  156.     NEW job  -> := NewM(SIZEOF job, MEMF_CLEAR)
  157.     job.replyport := self.myport
  158.     job.length := SIZEOF job
  159.  
  160.     job.status := JSTAT_SEND
  161.  
  162.     job.command := cmd
  163.     job.input := input
  164.     PutMsg(self.threadport, job)
  165.  
  166. ->    WriteF('Send job: adr = $\z\h[8]\n', job)
  167.  
  168. EXCEPT DO
  169.     ReThrow()
  170. ENDPROC job
  171.  
  172.  
  173.  
  174. PROC waitjob(job:PTR TO job) OF thread HANDLE
  175.     DEF    injob=NIL:PTR TO job,
  176.         status=0,
  177.         res=0
  178.  
  179. ->    WriteF('Waiting for job $\z\h[8] to finish\n', job)
  180.  
  181.     WHILE (job.status <> JSTAT_DONE) AND (job.status <> JSTAT_ABORTED)
  182.  
  183.         Wait(Shl(1, self.myport.sigbit))
  184.  
  185.         WHILE (injob := GetMsg(self.myport))
  186.             injob.status := JSTAT_DONE
  187. ->            WriteF('Got job reply, adr = $\z\h[8]\n', injob)
  188.         ENDWHILE
  189.     ENDWHILE
  190.  
  191.     res := job.result
  192.     status := job.status
  193.  
  194.     END job
  195.  
  196. EXCEPT DO
  197.     ReThrow()
  198. ENDPROC res, status
  199.  
  200.  
  201.  
  202. PROC break() OF thread
  203.     IF self.status = TSTAT_RUNNING
  204.         Signal(self.process, SIGBREAKF_CTRL_C)
  205.     ENDIF
  206. ENDPROC
  207.  
  208.  
  209.  
  210. PROC thread_main()
  211.     DEF    me=NIL:PTR TO process,
  212.         myport=NIL:PTR TO mp,
  213.         masterport=NIL:PTR TO mp,
  214.         startmsg=NIL:PTR TO job,
  215.         job=NIL:PTR TO job,
  216.         thread=NIL:PTR TO thread,
  217.         codeptr=NIL,
  218.         quit=FALSE,
  219.         sigs=0
  220.  
  221.     geta4()
  222.  
  223.     me := FindTask(NIL)
  224.  
  225.  
  226.  
  227.     /* get startup msg */
  228.     WaitPort(me.msgport)
  229.     startmsg := GetMsg(me.msgport)
  230.     startmsg.status := JSTAT_WORKING
  231.     masterport := startmsg.input[0]
  232.     codeptr := startmsg.input[1]
  233.     thread := startmsg.input[2]
  234.  
  235.     myport := createPort(NIL, 0)
  236.  
  237.     startmsg.result := myport
  238.  
  239.     ReplyMsg(startmsg)
  240.  
  241.  
  242.     WHILE quit=FALSE
  243.         sigs := Wait(SIGBREAKF_CTRL_C OR Shl(1, myport.sigbit))
  244.         IF (sigs AND SIGBREAKF_CTRL_C) THEN quit := TRUE
  245.  
  246.         WHILE (job := GetMsg(myport))
  247.             job.status := JSTAT_WORKING
  248.             job.result := codeptr(thread, job)
  249.             ReplyMsg(job)
  250.         ENDWHILE
  251.     ENDWHILE
  252.  
  253.     WHILE (job := GetMsg(myport))
  254.         job.status := JSTAT_ABORTED
  255.         ReplyMsg(job)
  256.     ENDWHILE
  257.  
  258.     thread.status := TSTAT_DEAD
  259. ENDPROC
  260.  
  261.  
  262.